<?php
/**************************************************************************
 * Naanal PHP Framework, Simple, Efficient and Developer Friendly
 * Ver 3.0, Copyright (C) <2010>  <Tamil Amuthan. R>
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ************************************************************************/
class ClsLZip extends ClsNaanalLibrary 
{
    private $zip=null;
    private $archiveName="";
    private $archiveFullPath="";
    private $archiveDirectory="";
    private $contentType="application/zip";
    private $arrSkipFile=array();
    private $isNewArchive=false;
    
    function __construct($archiveDirectory=".", $contentType = "application/zip")
    {
        $this->init($archiveDirectory, $contentType);
    }
    function init($archiveDirectory=".", $contentType = "application/zip")
    {
        if(!file_exists($archiveDirectory))
        {
            return false;
        }
        if($archiveDirectory[strlen($archiveDirectory)-1]!="/" && $archiveDirectory[strlen($archiveDirectory)-1]!="\\") $archiveDirectory=$archiveDirectory."/";
        $this->archiveDirectory=$archiveDirectory;
        $this->zip = new ZipArchive();
        return true;
    }
    function skip($arrFile)
    {
        $this->arrSkipFile=$arrFile;
    }
    function createNew($archiveName, $replace=true) 
    {
        return $this->create($archiveName, "application/zip", $replace);
    }
    function create($archiveName, $contentType = "application/zip", $replace=false) 
    {
        if(empty($this->archiveDirectory)) return false;
        $this->archiveName=$archiveName;
        $this->archiveFullPath=$this->archiveDirectory.$archiveName;
        if(file_exists($archiveName))
        {
            if($replace===true)
            {
                $this->zip->close();
                unlink($this->archiveFullPath);
            }
            $this->zip->open($this->archiveFullPath, ZIPARCHIVE::CREATE); 
            $this->isNewArchive=false;
        }
        else
        {
            $this->zip->open($this->archiveFullPath, ZIPARCHIVE::CREATE); 
            $this->isNewArchive=true;
        }
        $this->archiveName=$archiveName;
        $this->contentType=$contentType;
        $this->zip->open($this->archiveFullPath, ZIPARCHIVE::CREATE);
        return true;
    }
    
    public function addDirectory($directory,$arrSkipFile=array())
    {
        if(is_null($this->zip))
        {
            return false;
        }
        $basename=  basename($directory);
        $this->arrSkipFile=$arrSkipFile;
        $this->zip->addEmptyDir($basename);
        $success=$this->addDirectoryToZip($directory,$basename);
        return $success;
    }
    
    public function addDirectoryFiles($directory,$arrSkipFile=array())
    {
        $this->arrSkipFile=$arrSkipFile;
        $this->addDirectoryToZip($directory);
    }
    
    public function &getActiveZip()
    {
        return $this->zip;
    }

    private function addDirectoryToZip($folder, $subfolder = "") 
    {
        if(empty($this->archiveFullPath)) return false;
        if(!file_exists($folder))
        {
            return false;
        }
        $arr=str_split($folder);
        // we check if $folder has a slash at its end, if not, we append one
        $folder .= end($arr) == "/" ? "" : "/";
        if($subfolder!="")
        {
            $subfolder=$subfolder[strlen($subfolder)-1]=="/"?$subfolder:"{$subfolder}/";
        }
        $handle = opendir($folder);
        while ($f = readdir($handle)) {
            if ($f != "." && $f != "..") {
                if (is_dir($folder . $f)) {
                    $this->zip->addEmptyDir($subfolder . $f);
                    $this->addDirectoryToZip($folder . $f, $subfolder . $f);
                }
                else if (is_file($folder . $f)) 
                {
                    $filepath=$folder.$f;
                    $realpath=  realpath($filepath);
                    $arrPath=pathinfo($realpath);
                    
                    //$realarchivepath=  realpath($archiveName);
                    $arrArchivePath=pathinfo($this->archiveFullPath);
                    
                    if($arrArchivePath["dirname"]==$arrPath["dirname"] && $arrArchivePath["basename"]==$arrPath["basename"])
                    {
                        continue;
                    }
                    else if(in_array ($filepath,$this->arrSkipFile))
                    {
                        continue;
                    }
                    $this->zip->addFile($filepath, $subfolder . $f);
                }
            }
        }
        return true;
    }
    function &getZip()
    {
        return $this->zip;
    }
    function extract($destination, $entries=false)
    {
        if($entries===false)
        {
            try
            {
                $success=$this->zip->extractTo($destination);
            }
            catch(Exception $e)
            {
                trace($e);
            }
        }
        else
            $success=$this->zip->extractTo($destination, $entries);
        return $success;
    }
    function download()
    {
        $this->zip->close();
        $basename=  basename($this->archiveName);
        header('Content-Type: application/zip');
        header('Content-disposition: attachment; filename='.$basename);
        header('Content-Length: ' . filesize($this->archiveName));
        readfile($this->archiveName);
    }
}
?>